<template>
  <el-container style="width: 100%;height: 100%;">
    <!--    <el-container style="width: 100%;height: 100%;">-->
    <el-main
      style="height: 100%;margin-right: 10px;border-color: #E4E7ED;border-width: 10px"
    >
      <el-form>
        <el-row style="height: 100%">
          <el-col style="width: 320px">
            <el-form-item label="原始数据类型:">
              <div style="text-align: left">
                <!--              el-select默认居中显示，外面加一层div控制位置-->
                <el-select v-model="srcDataType" placeholder="请选择">
                  <el-option
                    v-for="item in srcDataTypeList"
                    :key="item.idx"
                    :label="item.value"
                    :value="item.value"
                  ></el-option>
                </el-select>
              </div>
            </el-form-item>
          </el-col>
          <el-col style="width: 300px" v-show="showCharDataType">
            <el-form-item label="字符类型:">
              <div style="text-align: left">
                <!--              el-select默认居中显示，外面加一层div控制位置-->
                <el-select v-model="charDataType" placeholder="请选择">
                  <el-option
                    v-for="item in charDataTypeList"
                    :key="item.idx"
                    :label="item.value"
                    :value="item.value"
                  ></el-option>
                </el-select>
              </div>
            </el-form-item>
          </el-col>
          <el-input
            type="textarea"
            :rows="10"
            placeholder="请输入内容"
            v-model="srcTextarea"
            style="margin-top: 5px"
          >
          </el-input>
        </el-row>
      </el-form>

      <el-form style="margin-top: 10px">
        <el-form-item label="结果数据类型:">
          <div style="text-align: left">
            <!--              el-select默认居中显示，外面加一层div控制位置-->
            <el-select v-model="dstDataType" placeholder="请选择">
              <el-option
                v-for="item in dstDataTypeList"
                :key="item.idx"
                :label="item.value"
                :value="item.value"
              ></el-option>
            </el-select>
            <el-button
              style="margin-left: 5px"
              v-on:click="fLowerCase"
              v-show="showLowerCaseBtn"
              >lowercaseString
            </el-button>
          </div>
          <el-input
            type="textarea"
            :rows="10"
            placeholder="显示结果"
            v-model="dstTextarea"
            style="margin-top: 5px"
          >
          </el-input>
        </el-form-item>
      </el-form>
      <el-row>
        <el-button type="primary" style="width: 300px" v-on:click="fTransform"
          >转换
        </el-button>
        <el-button
          type="primary"
          style="width: 300px"
          v-on:click="fTransformReverse"
          >反转换
        </el-button>
      </el-row>
    </el-main>

    <el-aside>
      <el-form style="margin-left: 15px">
        <el-form-item style="color: chocolate">配置参数</el-form-item>
        <el-form-item label="转换类型:">
          <el-select v-model="transformType" placeholder="请选择">
            <el-option
              v-for="item in transformList"
              :key="item.idx"
              :label="item.value"
              :value="item.value"
            ></el-option>
          </el-select>
        </el-form-item>
        <!--          //所有内容都包含在el-form-item，否则高度不正常-->
        <el-form-item label="" style="text-align: left">
          <el-checkbox
            v-model="customChecked"
            label="自定义编码表"
            style="margin-left: 0px"
          ></el-checkbox>
          <el-input
            type="textarea"
            :rows="4"
            placeholder="请输入内容"
            v-model="customBase64Code"
            style="margin-top: 5px"
          >
          </el-input>
          <el-checkbox
            v-model="customPadding"
            label="自定义不足补位字符(标准为=)"
            style="margin-left: 0px"
          ></el-checkbox>
          <el-input
            type="textarea"
            :rows="1"
            placeholder="请输入内容"
            v-model="customBase64Padding"
            style="margin-top: 5px"
          >
          </el-input>
        </el-form-item>
      </el-form>
    </el-aside>
  </el-container>
</template>

<script>
import Crypto from "crypto-js";
import { LBXCustomBase64 } from "../JS/LBXCustomBase64";
import { Hex } from "../JS/hex";

export default {
  name: "Transform",
  data() {
    return {
      srcDataTypeList: [
        { value: "plain-utf8", idx: "1" },
        { value: "hex", idx: "2" },
        { value: "base64", idx: "3" }
      ],
      srcDataType: "plain-utf8",
      srcTextarea: "",

      dstDataTypeList: [
        { value: "plain-utf8", idx: "0" },
        { value: "hex", idx: "1" },
        { value: "base64", idx: "2" }
      ],
      dstDataType: "plain-utf8",
      dstTextarea: "",

      // type BufferEncoding = "ascii" | "utf8" | "utf-8" | "utf16le" | "ucs2" | "ucs-2" | "base64" | "latin1" | "binary" | "hex";
      charDataTypeList: [
        { value: "utf8", idx: "1" },
        { value: "ascii", idx: "2" },
        { value: "latin1", idx: "3" },
        { value: "ucs2", idx: "4" }
      ],
      charDataType: "utf8",

      transformList: [
        { value: "Base64", idx: "1" },
        { value: "Hex", idx: "2" }
      ],
      transformType: "Base64",
      customChecked: false,
      customPadding: false,
      customBase64Code:
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",
      customBase64Padding: "="
    };
  },
  computed: {
    showLowerCaseBtn: function() {
      return this.dstDataType == "hex" ? true : false;
    },
    showCharDataType: function() {
      // return this.srcDataType == "plain" ? true : false;
      return false;
    }
  },
  methods: {
    fTransform: function() {
      this.dstDataType = "plain";

      switch (this.transformType) {
        case "Base64":
          {
            if (this.srcDataType == "base64") this.srcDataType = "plain";

            if (this.customChecked || this.customPadding) {
              let standardBaseCode =
                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

              console.log("custom base64");
              let bs = new LBXCustomBase64();
              bs.initCustomEncodeChars(
                this.customChecked ? this.customBase64Code : standardBaseCode,
                this.customPadding ? this.customBase64Padding : "="
              );

              switch (this.srcDataType) {
                case "plain":
                  {
                    let srcHex = Crypto.enc.Utf8.parse(
                      this.srcTextarea
                    ).toString();
                    let inputBytes = Hex.decode(srcHex);
                    this.dstTextarea = bs.encode(inputBytes);
                  }
                  break;
                case "hex":
                  {
                    //待加密byte
                    let inputBytes = Hex.decode(this.srcTextarea);
                    this.dstTextarea = bs.encode(inputBytes);
                  }
                  break;
              }
            } else {
              switch (this.srcDataType) {
                case "plain":
                  //base64
                  this.dstTextarea = Crypto.enc.Base64.stringify(
                    Crypto.enc.Utf8.parse(this.srcTextarea)
                  ); //base64编码;
                  break;
                case "hex":
                  this.dstTextarea = Crypto.enc.Base64.stringify(
                    Crypto.enc.Hex.parse(this.srcTextarea)
                  ); //base64编码;
                  break;
              }
            }
          }

          break;
        case "Hex":
          {
            if (this.srcDataType == "hex") this.srcDataType = "plain";

            switch (this.srcDataType) {
              case "plain":
                //base64
                this.dstTextarea = Crypto.enc.Utf8.parse(
                  this.srcTextarea
                ).toString(Crypto.enc.Hex);

                break;
              case "base64":
                this.dstTextarea = Crypto.enc.Base64.parse(
                  this.srcTextarea
                ).toString(Crypto.enc.Hex);
                break;
            }
          }
          break;
      }
    },

    fTransformReverse: function() {
      switch (this.transformType) {
        case "Base64":
          {
            this.srcDataType = "plain";
            if (this.dstDataType == "base64") this.dstDataType = "plain";

            if (this.customChecked || this.customPadding) {
              let standardBaseCode =
                "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

              console.log("custom base64");
              let bs = new LBXCustomBase64();
              bs.initCustomEncodeChars(
                this.customChecked ? this.customBase64Code : standardBaseCode,
                this.customPadding ? this.customBase64Padding : "="
              );

              let deBase64 = bs.decode(this.srcTextarea);
              console.log("deBase64 type");
              console.log(typeof deBase64 == "string");
              switch (this.dstDataType) {
                case "plain":
                  {
                    // let dstBytes = this.stringToBytes(deBase64);
                    this.dstTextarea = Hex.encode(deBase64, 0, deBase64.length);

                    this.dstTextarea = Crypto.enc.Hex.parse(
                      this.dstTextarea
                    ).toString(Crypto.enc.Utf8);
                  }
                  break;
                case "hex":
                  {
                    // let dstBytes = this.stringToBytes(deBase64);
                    this.dstTextarea = Hex.encode(deBase64, 0, deBase64.length);
                  }
                  break;
              }
            } else {
              switch (this.dstDataType) {
                case "plain":
                  this.dstTextarea = Crypto.enc.Base64.parse(
                    this.srcTextarea
                  ).toString(Crypto.enc.Utf8);
                  break;

                case "hex":
                  this.dstTextarea = Crypto.enc.Base64.parse(
                    this.srcTextarea
                  ).toString(Crypto.enc.Hex);
                  break;
              }
            }
          }
          break;
        case "Hex":
          {
            this.dstDataType = "plain";
            this.dstTextarea = Crypto.enc.Hex.parse(this.srcTextarea).toString(
              Crypto.enc.Utf8
            );
          }
          break;
      }
    },

    fLowerCase: function() {
      this.dstTextarea = this.dstTextarea.toLowerCase();

      var plainUtf8 = "1111";

      let plainBuffer = Buffer.from(plainUtf8, "utf-8");

      //-> hex
      let hex = plainBuffer.toString("hex");
      console.log("hex:" + hex);

      var wordArray = Crypto.enc.Hex.parse(hex);
      console.log(wordArray);

      // Encrypt
      let ciphertext = Crypto.AES.encrypt(
        wordArray,
        "secret key 123"
      ).toString();
      //base64
      console.log("encrypt base64:" + ciphertext);

      // Decrypt
      let bytes = Crypto.AES.decrypt(ciphertext, "secret key 123");
      // var decryptedData = JSON.parse(bytes.toString(Crypto.enc.Utf8));

      console.log(bytes); // [{id: 1}, {id: 2}]

      //hex
      console.log(bytes.toString());

      console.log(Buffer.from(bytes.toString(), "hex").toString("utf8"));

      console.log("above plain");

      //->base64
      let base64 = plainBuffer.toString("base64");
      console.log("base64:" + base64);

      //->string utf-8
      let utf8 = plainBuffer.toString("utf-8");
      console.log("utf8:" + utf8);

      //byte数组
      console.log(typeof plainBuffer.buffer);
      console.log(plainBuffer.buffer);

      console.log("hex to buf:");
      console.log(Buffer.from(hex, "hex"));

      let str1 = Buffer.from(hex, "hex").toString("utf-8");
      console.log("hex to utf-8 string:" + str1);

      //json与string相互转换
      this.json2String();

      //test encrpto
      this.testEncrypto();
    },
    hexToString: function(hex) {
      var arr = hex.split("");
      var out = "";

      for (var i = 0; i < arr.length / 2; i++) {
        var tmp = "0x" + arr[i * 2] + arr[i * 2 + 1];
        var charValue = String.fromCharCode(tmp);
        out += charValue;
      }
      return out;
    },
    json2String: function() {
      //json,注意手动拼写格式
      let json = '{ "name": "cxh", "sex": "man" }';
      // let json  = { name: "cxh", sex: "man" };

      if (typeof json == "string") {
        //string->json
        console.log("string object");
        let str;
        try {
          str = JSON.parse(json);
          console.log("string->json" + str);
        } catch (e) {
          console.log("err:" + str);
        }
      } else {
        //json -> string
        let jsonobj = JSON.stringify(json);
        console.log("json->string:" + jsonobj + typeof jsonobj);
      }
    }
  },
  created() {
    // 方便控制台获取当前vue进行数据调试
    window.Transform = this;
  }
};
</script>

<style scoped>
.el-main {
  background-color: #e9eef3;
  color: #333;
  text-align: center;
  line-height: 50px;
}

.left {
  text-align: left;
}

.el-aside {
  display: block;
  position: relative;
  /*overflow-y: scroll;*/
  /*background-color: #324157 !important;*/
  width: 300px;
  border-left-color: #c8c8c8;
  border-left-style: solid;
  border-left-width: 1px;
}
</style>
